﻿using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Newtonsoft;
using HR60_PanelSoft.Model;
using HR60_PanelSoft.Model.BaseModel;

namespace HR60_PanelSoft.FileUtils
{
	public class JsonFileUtils
	{
		/// <summary>
		/// 面板类型全集文件
		/// </summary>
		public const string FILE_PANEL_TYPES = "PanelTypes.json";

		/// <summary>
		/// 设备类型全集文件
		/// </summary>
		public const string FILE_DEVICE_TYPES = "DeviceTypes.json";

		/// <summary>
		/// 自动保存文件
		/// </summary>
		public const string FILE_AUTO_SAVE = "AutoSave.json";

		/// <summary>
		/// 读Json文件
		/// </summary>
		/// <returns>The json from file.</returns>
		/// <param name="file">File.</param>
		public static object readJsonFromFile(string file)
		{
			using(StreamReader sr= new StreamReader (System.AppDomain.CurrentDomain.BaseDirectory + "Resources/" + file, Encoding.UTF8))
			{
				string jstr = sr.ReadToEnd ();
				return JavaScriptConvert.DeserializeObject (jstr);
			}
		}

		/// <summary>
		/// 保存项目
		/// </summary>
		/// <param name="proj"></param>
		/// <param name="filePath"></param>
		public static void saveProj(Proj proj, string filePath)
		{
			string json = JavaScriptConvert.SerializeObject(proj);

			// 写入文件
			using (StreamWriter sw = new StreamWriter (filePath))
			{
				sw.Write (json);
			}
		}

		/// <summary>
		/// 读取项目
		/// </summary>
		/// <param name="proj"></param>
		/// <param name="filePath"></param>
		/// <returns></returns>
		public static Proj loadProj(Proj proj, string filePath)
		{
			using (StreamReader sr = new StreamReader(filePath))
			{
				string str = sr.ReadToEnd ();
                Proj tempproj = (Proj)JavaScriptConvert.DeserializeObject (str, typeof(Proj));
                return tempproj;
			}
		}

		/// <summary>
		/// 读取面板类型全集
		/// </summary>
		/// <returns></returns>
		public static List<PanelType> loadPanelTypes()
		{
			List<PanelType> list = new List<PanelType> ();
			JavaScriptArray jarray = (JavaScriptArray) readJsonFromFile (FILE_PANEL_TYPES);
			for (int i=0; i<jarray.Count; i++)
			{
				PanelType pt = new PanelType ();
				JsonPlus jp = new JsonPlus((JavaScriptObject)jarray [i]);

				pt.name = jp.getString ("name");
				pt.protocolTag = jp.getString ("protocolTag");
				pt.lPinLen = jp.getInt ("lPinLen");
				pt.tPinLen = jp.getInt ("tPinLen");
				pt.hasEplusModel = jp.getBoolean ("hasEplusModel");
				pt.hasM485Model = jp.getBoolean ("hasM485Model");
				pt.hasSignalModel = jp.getBoolean ("hasSignalModel");
				pt.hasStyle = jp.getBoolean ("hasStyle");
				pt.hasExPage = jp.getBoolean ("hasExPage");
				pt.maxPage = jp.getInt ("maxPage");
				pt.maxScenePage = jp.getInt("maxScenePage");
				pt.buttonsPerPage = jp.getInt ("buttonsPerPage");
				list.Add (pt);
			}
			return list;
		}

		/// <summary>
		/// 读取设备类型全集
		/// </summary>
		/// <returns></returns>
		public static List<DeviceType> loadDeviceTypes()
		{
			List<DeviceType> list = new List<DeviceType> ();
			JavaScriptArray jarray = (JavaScriptArray) readJsonFromFile (FILE_DEVICE_TYPES);
			for (int i=0; i<jarray.Count; i++)
			{
				JsonPlus jp = new JsonPlus((JavaScriptObject)jarray [i]);
				DeviceType dt = json2DeviceType (jp);

				// sub device type
				JsonPlus subJp = jp.get ("subDeviceType");
				if (subJp != null)
				{
					dt.subDeviceType = json2DeviceType (subJp);
				}
				list.Add (dt);
			}
			return list;
		}

		/// <summary>
		/// 解析设备类型，不解析子设备
		/// </summary>
		/// <returns>The device type.</returns>
		/// <param name="jp">Jp.</param>
		private static DeviceType json2DeviceType(JsonPlus jp)
		{
			DeviceType dt = new DeviceType ();


			string exTypeString = jp.getString ("exType");
			if(exTypeString != null) dt.exType = (ExDeviceType) Enum.Parse (typeof(ExDeviceType), exTypeString);

			// 接入类型
			string pinTypeString = jp.getString ("pinType");
			if (pinTypeString != null) dt.pinType = (PinType) Enum.Parse (typeof(PinType), pinTypeString);

			// 开关类型列表，与pin数量对应
			string switchTypesString = jp.getString ("switchTypes");
			if(switchTypesString != null)
			{
				string[] sts = switchTypesString.Split (new char[] { ',' });
				for(int i=0; i<sts.Length; i++)
				{
					dt.switchTypes.Add((SwitchType) Enum.Parse(typeof(SwitchType), sts[i].Trim()));
				}
			}

			// 可控属性列表
			JsonPlus[] attrJsons = jp.getArray ("attrs");
			if (attrJsons != null)
			{
				for (int i=0; i<attrJsons.Length; i++) 
				{
					JsonPlus aj = attrJsons [i];
					CtrlAttr attr = new CtrlAttr ();
					attr.name = aj.getString ("name");
					attr.protocolTag = aj.getString ("protocolTag");

					// 可控属性值列表
					JavaScriptObject values = (JavaScriptObject)aj.getObject("values");
					foreach (KeyValuePair<string, object> kp in values)
					{
						attr.values.Add (kp.Key, kp.Value);
					}
					dt.attrs.Add (attr);
				}
			}

			// 厂商列表
			JsonPlus[] brandJsons = jp.getArray ("brands");
			if (brandJsons != null) 
			{
				for (int i=0; i<brandJsons.Length; i++)
				{
					JsonPlus bj = brandJsons [i];
					DeviceBrand brand = new DeviceBrand ();
					brand.name = bj.getString ("name");
					brand.protocolTag = bj.getString ("protocolTag");
					dt.brands.Add (brand);
				}
			}

			dt.name = jp.getString ("name");
			dt.protocolTag = jp.getString ("protocolTag");
			dt.group = jp.getString ("group");
			dt.pinLen = jp.getInt ("pinLen");
			dt.subDeviceMax = jp.getInt ("subDeviceMax");
			dt.canButtonCtrl = jp.getBoolean ("canButtonCtrl");
			return dt;
		}
	}
}
